home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* nmail
- /* SUMMARY
- /* extract originator and subject from new mail received by cico
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* nmail
- /* SYNOPSIS
- /* nmail [-d debuglevel]
- /* DESCRIPTION
- /* nmail searches for new mail files received by cico and extracts
- /* the originator's name, and message subject for later use by the
- /* mail visual shell.
- /*
- /* Return address formats we understand (in order of preference):
- /* .nf
- /*
- /* From: address (full_name) (take full_name)
- /* From: full_name <address> (take full_name)
- /* From: address (take address)
- /* >From address (take address)
- /* From address (take address)
- /*
- /* .fi
- /* To avoid tampering, new files will have read-only permission.
- /*
- /* In order to avoid corruption, control-c interrupts are disabled
- /* while this program executes.
- /* FILES
- /* In the spool directory:
- /* n<seqno> received mail message
- /* h<seqno> extracted originator name, subject
- /* SEE ALSO
- /* path(5) spool directory, file names
- /* cico(1) network process
- /* mail(1) visual mail shell
- /* DIAGNOSTICS
- /* Exit status zero when no errors were detected, nonzero in case of file
- /* access errors. See status(5) for error codes.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Tue Mar 31 20:14:11 GMT+1:00 1987
- /* LAST MODIFICATION
- /* 90/01/22 13:02:20
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <stdio.h>
- #include <signal.h>
- #include <time.h>
- #include <ctype.h>
- #include <varargs.h>
-
- #include "defs.h"
- #include "ndir.h"
- #include "path.h"
- #include "status.h"
- #include "ms_parse.h"
-
- extern struct tm *localtime(); /* system functions */
-
- hidden void parse_args(); /* forward declarations */
- hidden void newmail();
- hidden void extract();
- hidden void usage();
-
- hidden int dflag = 0; /* debugging option */
-
- #define debug if (dflag) printf
-
- public char *progname = "nmail";
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- signal(SIGINT, SIG_IGN); /* disable ctrl-c */
- parse_args(argc, argv); /* parse command args */
- if (pathinit()) /* get path info */
- exit(E_NOSPOOL); /* bad MAILDIR variable */
- umask(0222); /* make files read-only */
- newmail(); /* get headers from new mail */
- exit(0);
- /* NOTREACHED */
- }
-
- /* parse_args - process command-line arguments */
-
- hidden void parse_args(argc, argv)
- int argc;
- char **argv;
- {
- while (--argc && *++argv && **argv == '-') {/* process options */
- switch (*++*argv) {
- case 'd': /* turn debugging on */
- if (--argc == 0)
- usage("missing debugging level argument");
- if ((dflag = atoi(*++argv)) < 0 || dflag > 9)
- dflag = 0;
- break;
- default: /* unknown option */
- usage("invalid option: -%c", **argv);
- break;
- }
- }
-
- /* check for extraneous arguments */
-
- if (argc > 0)
- usage("unexpected argument: %s", *argv);
- }
-
- /* scan for new mail that hasn't gotten yet a metafile */
-
- hidden void newmail()
- {
- register DIR *dp;
- struct direct *de;
- unsigned msgno;
-
- debug("directory: \"%s\"\n", maildir);
-
- /*
- * Scan the spool directory for newly-arrived mail.
- *
- * Incoming mail message files have a name of "n<seqno>". The originator
- * name is normally present in files with names "h<seqno>" or "o<seqno>".
- * The presence of an "o" file implies that the file "n<seqno>" has been
- * read by the user. An "h" file means that the user has not yet read the
- * message file.
- *
- * If a message file has no corresponding "h" or "o" file we assume it is a
- * new mail message and create an "h" file with the name of the
- * originator and the subject of the message.
- */
-
- if ((dp = opendir(maildir)) == 0)
- exit(E_NOSPOOL);
-
- while (de = readdir(dp)) {
- debug("nmail: file \"%s\"\n", de->d_name);
- if (de->d_name[0] == NEW_MESG
- && (msgno = seqno(de->d_name))) {
- if (access(old_meta(msgno), 4) == 0) {
- /* already marked as read */ ;
- } else if (access(new_meta(msgno), 4) == 0) {
- /* already marked as unread */ ;
- } else { /* create meta file */
- extract(new_mesg(msgno), new_meta(msgno));
- }
- }
- }
- closedir(dp);
- }
-
- /* extract - extract originator and subject info from mail file to meta file */
-
- hidden void extract(mail, meta)
- char *mail;
- char *meta;
- {
- FILE *mesgfp,
- *metafp;
- char line[MAXLINE];
- char from[MAXLINE]; /* name of sender */
- char subj[MAXLINE]; /* message subject */
- int context = MS_UUCP;
-
- debug("-- \"%s\" -> \"%s\"\n", mail, meta);
-
- if ((mesgfp = fopen(mail, "r")) == NULL) /* cannot open existing file */
- exit(E_SYSFAIL);
-
- strcpy(from, "Somewhere"); /* default originator */
- subj[0] = '\0'; /* initialize subject */
-
- /*
- * Some mailers generate real headers, separated from the message body by
- * an empty line. So we stop when we find an empty line. Other mailers
- * have no headers, so we stop when we see no header line. The following
- * algorithm tries to extract the real user name if possible, otherwise
- * it takes whatever it can get.
- */
-
- while ((context != MS_BODY) && fgets(line, sizeof(line), mesgfp)) {
- switch (context = ms_parse(context, line)) {
- case MS_UUCP:
- if (sscanf(line, "%*[>] From %s", from) != 1)
- (void) sscanf(line, "From %s", from);
- break;
- case MS_HEADER:
- if (hscanf(line, "Subject:", " %[^\n]", subj) == 0
- && hscanf(line, "From:", " %*s ( %[^)] )", from) == 0)
- (void) hscanf(line, "From:", " %[^<] <", from);
- break;
- }
- }
-
- /* carefully check all went well */
-
- if (ferror(mesgfp)) /* sorry, read problem */
- exit(E_READERR);
- if ((metafp = fopen(meta, "w")) == NULL) /* cannot create metafile */
- exit(E_WRITERR);
- fprintf(metafp, "%s\n%s\n", from, subj); /* write originator, subject */
- if (ferror(metafp)) {
- (void) fclose(metafp); /* ms-dog needs this! */
- (void) chmod(meta, 0666); /* sorry, write problem */
- (void) unlink(meta); /* delete metafile */
- exit(E_WRITERR);
- }
- (void) fclose(mesgfp);
- (void) fclose(metafp);
- }
-
- /* usage - explain what is wrong */
-
- /* VARARGS */
-
- hidden void usage(va_alist)
- va_dcl
- {
- va_list ap;
- char *fmt;
-
- va_start(ap);
- fmt = va_arg(ap, char *);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fprintf(stderr, "\nusage: nmail [-d debugging_level]\n");
- exit(2);
- }
-